//edited
module mytimer (
    input          clk_50M,
    input          reset_n,               // reset.reset
    
    input   [3:0]     avs_s0_address,     //    s0.address
    input             avs_s0_read,        //      .read
    input             avs_s0_write,       //      .write
    output reg [31:0] avs_s0_readdata,    //      .readdata
    input   [31:0]    avs_s0_writedata,   //      .writedata
    input             device_req, //      .waitrequest
    output reg        device_ack, //      .waitrequest
    input   [3:0]     avs_s0_byteenable,    //      .readdata
    output reg        irq_req,
    input             irq_ack
  );

  reg [15:0] timer16;
  reg [31:0] timer32;
  reg [31:0] timer32Slow;
  reg [31:0] timer32Top;
  
  reg [5:0] tick;
  reg       tick50;
  reg [9:0] tickslow;
  reg       tick50000;
  always @ (posedge clk_50M or negedge reset_n) begin
    if (!reset_n) begin
      tick <= 0;
      tick50 <= 0;
      tickslow <= 0;
      tick50000 <= 0;
    end else begin
      tick <= tick + 1'b1;
      tick50 <= 0;
      tick50000 <= 0;
      if(tick==50) begin
        tick<=0;
        tick50 <= 1;
        tickslow <= tickslow + 1'b1;
        if(tickslow==1000) begin
          tickslow<=0;
          tick50000 <= 1;
        end
      end

      
    end
  end
  
  always @ (*) begin
    case(avs_s0_address[1:0])
    0:avs_s0_readdata<={16'b0,timer16};
    1:avs_s0_readdata<=timer32;
    2:avs_s0_readdata<=timer32Slow;
    3:avs_s0_readdata<=0;
    endcase
  end
  
  reg device_req_buff;
  always @ (posedge clk_50M or negedge reset_n) begin
    if (!reset_n) begin
      device_req_buff <= 0;
      timer16 <= 0;
      timer32 <= 0;
      timer32Slow <= 0;
      timer32Top <= 32'hFFFFFFFF;
      irq_req <= 0;
    end else begin
      device_req_buff <= device_req;
      
      if(tick50)begin
        if(timer16!=16'hFFFF)begin
          timer16<=timer16+1'b1;
        end
        timer32<=timer32+1'b1;
        if(timer32==timer32Top)begin 
          timer32<=0;
          irq_req<=1;
        end
      end

      if(tick50000)begin
        timer32Slow<=timer32Slow+1'b1;
      end

      if(device_req_buff && !device_ack)begin
        device_ack <= 1;
        if(avs_s0_write) begin
          case(avs_s0_address[1:0])
          0:timer16<=avs_s0_writedata[15:0];
          1:timer32<=avs_s0_writedata;
          2:timer32Top<=avs_s0_writedata;
          endcase
        end
      end

      if(!device_req_buff && device_ack)begin
        device_ack <= 0;
      end
      
      if(irq_ack)begin
        irq_req <= 0;
      end

    end
  end

endmodule
